﻿// Ftp服务端.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#include "Ws2tcpip.h"
#include <string>
#include <fstream>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")
using namespace std;

int main()
{
	// tcp连接部分
	WORD wVersionRequested;      // 用来指定准备要加载到套接字库的版本
	WSADATA wsaData;             // 库版本的有关信息
	wVersionRequested = MAKEWORD(1,1);
	// WSAStartup():①加载套接字库②进行套接字版本的协商,确定要使用的套接字的版本
	WSAStartup(wVersionRequested, &wsaData);  // 加载套接字库
	// socket:创建套接字
	// AF_INET:指定地址族;SOCK_STREAM:指定Socket的类型为流式套接字;Protocol:指定与地址族相关的协议
	unsigned int  sockSrv = socket(AF_INET,SOCK_STREAM,0);  // 创建套接字
	SOCKADDR_IN  addrSrv;  // 指定了该套接字本地地址信息

	// 表示地址族，对于IP地址,将一直是AF_INET 
	addrSrv.sin_family = AF_INET;  
	// 套接字的主机IP地址
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 
	// htons:将u_short值从主机字节顺序转化为TCP/IP网络字节顺序 // 指定要分配给套接字的端口号
	addrSrv.sin_port = htons(8888);  
	// 将Socket与本地的IP地址和端口号绑定
	bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));  

	// listen():将指定的套接字设置为监听模式
	// backlog:等待连接队列的最大长度
	listen(sockSrv,5);  

	SOCKADDR_IN addrClient;
	int len = sizeof(SOCKADDR);
	// accept():接受客户端发送的连接请求
	// sockSrv:当前监听的Socket; addrClient:连接的客户端的IP地址和端口号
	unsigned int SockConn = accept(sockSrv, (SOCKADDR*)&addrClient,&len);  

	// 接收ftp client发送的文件的文件长度
	char sizeFileStr[20] = {0};
	// 从一个已连接的套接字中接收数据
	recv(SockConn, sizeFileStr, sizeof(sizeFileStr)-1,0);   
	int fileSize = atoi(sizeFileStr);

	// 接收ftp client发送的文件的并保存
	char recvBuf[1024] = {0};
	int recvTotalSize = 0;

	char* buffer;
	char absolutePath[MAX_PATH];
	memset(absolutePath, 0, MAX_PATH);
	GetModuleFileNameA(NULL, absolutePath, MAX_PATH);
	string strPath = (std::string)absolutePath;
	int nPos = strPath.find_last_of('\\', strPath.length());
	string strDirectory = strPath.substr(0, nPos);  // 返回不带有可执行文件名的路径
	char* pFileName = "\\2.txt";
	buffer = const_cast<char*>(strDirectory.c_str());
	strcat(buffer, pFileName);
	std::fstream fs;
	fs.open(buffer, std::ios::in);
	if (!fs)
	{
		ofstream fout(buffer);
		if (fout)
		{
			fout << "写入内容，也可以不写入" << endl;
			fout.close();
		}
	}
	else
	{
		std::cout << "该文件已经存在！" << endl;
	}

	FILE* fp = fopen(buffer, "wt");
	while (recvTotalSize<fileSize)
	{
		int recvSize = recv(SockConn,recvBuf,sizeof(recvBuf),0);
		recvTotalSize += recvSize;
		printf("recved %d MB\n", recvTotalSize/(1024*1024));
		fwrite(recvBuf,1,recvSize,fp);
	}
	fclose(fp);

	if (recvTotalSize == fileSize)
	{
		printf("Done!");
	}
	else
	{
		printf("Error!");
	}

	closesocket(sockSrv);   // 关闭已建立连接的套接字
	WSACleanup();           // 终止对套接字到使用
	getchar();
    return 0;
}

